﻿Imports PTIC_Util
Imports Actuariat
Imports System.Data

#Region "Interfaces comportementales"
Public Interface IGestionConversions
    Function convStrToTypedParam(Of typeParam)(ByVal valeurUnique As String) As typeParam
End Interface
#End Region

#Region "Liste de contrôleurs non typés"
Public Interface IListControleursParametres
    Function setValeurUniqueFromValeurAffichee(ByVal nomParametre As String, ByVal valeurUnique As String) As resultatValidationContraintes
    Function setValeurUniqueFromObject(ByVal nomParametre As String, ByVal valeurUnique As Object) As resultatValidationContraintes
    Function setValeursDataTable(ByVal nomParametre As String, ByVal valeursDataTable As DataTable) As resultatValidationContraintes
    Function setValeursFromExt(ByVal nomParametre As String, ByVal valeursExt As DataTable) As resultatValidationContraintes

    Function isValeurUniqueAfficheeValide(ByVal nomParametre As String, ByVal valeurUnique As String) As resultatValidationContraintes
    Function isValide(ByVal nomParametre As String, ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes
    Function isListeParametresValide() As resultatValidationContraintes
    Sub addRegle(ByVal nomParametre As String, ByVal regle As Object)
    Sub defaut()

    Function getDescription(ByVal nomParametre As String) As String
    Function getNature(ByVal nomParametre As String) As paramNature
    Function getMethode_cal(ByVal nomParametre As String) As Boolean()
    Function getValeurUniqueAffichee(ByVal nomParametre As String) As String
    Function getValeurUnique(ByVal nomParametre As String) As Object
    Function getValeursDataTable(ByVal nomParametre As String) As DataTable
    Function getValeursSeg(ByVal nomParametre As String) As List(Of String)
    Function getControleur(ByVal nomParametre As String) As controleurParamNonTyped
End Interface
Public Class baseControleurListParametres
    Implements IListControleursParametres

    'Dans cet objet, une implémentation doit permettre de créer un contrôleur à partir d'un paramètre typé
    'i.e on ajoute un paramètre typé et il ajoute un contrôleur (il faut lui envoyer la fabrique de contrôleur)
    Protected _lControleParametre As Dictionary(Of String, controleurParamNonTyped)

    Public Sub New()
        _lControleParametre = New Dictionary(Of String, controleurParamNonTyped)
    End Sub

    'Ajoute un contrôle à un paramètre typé
    Public Sub addTypedParametre(Of typeParametre)(ByVal typedParametre As generiqueTypedParametreV2(Of typeParametre), _
                                                   ByVal baseFabriqueControleur As fabriqueControleurParametreTyped)
        'Création du contrôleur en fonction du paramètre typé en paramètre
        'Le contrôleur associé au paramètre est créé par l'intermédiaire d'une fabrique transmise en paramètre
        'Pour changer le contrôleur associé, il suffit de créer une nouvelle fabrique de contrôleur
        _lControleParametre.Add(typedParametre.nom, _
                                baseFabriqueControleur.newcontroleur(Of typeParametre)(typedParametre))
    End Sub
    Public Sub addParametreSelectionMedicale(ByVal parametreSelectionMedicale As parametreSelectionMedicale)
        _lControleParametre.Add(parametreSelectionMedicale.nom, _
                                New controleurSelectionMedicale(parametreSelectionMedicale))
    End Sub
    Public Sub defaut() Implements IListControleursParametres.defaut
        _lControleParametre(csteParam.nomTx_TaxeAssu).setValeurUniqueFromObject(0.09)
        _lControleParametre(csteParam.nomTx_TechA).setValeurUniqueFromObject(0.02)
        _lControleParametre(csteParam.nomTx_RembAntiA).setValeurUniqueFromObject(0.05)
        _lControleParametre(csteParam.nomTx_RendActifsA).setValeurUniqueFromObject(0.04)
        _lControleParametre(csteParam.nomTx_TaxeImpoA).setValeurUniqueFromObject(1 / 3)
        _lControleParametre(csteParam.nomTx_RendActionnairesA).setValeurUniqueFromObject(0.1)
        _lControleParametre(csteParam.nomTx_CoutEmprSuboA).setValeurUniqueFromObject(0.0024)
        _lControleParametre(csteParam.nomTx_fraiGestA).setValeurUniqueFromObject(0.075)
        _lControleParametre(csteParam.nomTx_CommiContA).setValeurUniqueFromObject(0.42)
        _lControleParametre(csteParam.nomTx_CouvEmprSuboA).setValeurUniqueFromObject(0.25)
        _lControleParametre(csteParam.nomTx_FondPropSurMSR).setValeurUniqueFromObject(1.14)
        _lControleParametre(csteParam.nomTable_Mortalite_F).setValeurUniqueFromObject("Table_DC_Empr_F.sas7bdat")
        _lControleParametre(csteParam.nomAge_FinDC).setValeurUniqueFromObject(70)
        _lControleParametre(csteParam.nomPres_GarantiePTIA).setValeurUniqueFromObject(True)
        _lControleParametre(csteParam.nomTx_PrixGarantiePTIA).setValeurUniqueFromObject(0.03)
        _lControleParametre(csteParam.nomTx_Majo_sinDCPTIA).setValeurUniqueFromObject(0.12)
        _lControleParametre(csteParam.nomSel_medic).setValeurUniqueFromObject("AUCUNE")
        _lControleParametre(csteParam.nomTble_maintien_incinv).setValeurUniqueFromObject("Maint_INCINV_horsFRA_CNP.sas7bdat")
        _lControleParametre(csteParam.nomAge_FinINCINV).setValeurUniqueFromObject(65)
        _lControleParametre(csteParam.nomfranchise_INCAP).setValeurUniqueFromObject(3)
        _lControleParametre(csteParam.nomTx_abat_MalaNonObje).setValeurUniqueFromObject(0.2)
        _lControleParametre(csteParam.nomTx_abat_ExclPerteRev).setValeurUniqueFromObject(0.3)
        _lControleParametre(csteParam.nomTx_MajoPrudSinINCINV).setValeurUniqueFromObject(0.045)
        _lControleParametre(csteParam.nomTx_chgtSecuINCINV).setValeurUniqueFromObject(0.15)
        _lControleParametre(csteParam.nomTx_mensEntreeINCINV).setValeurUniqueFromObject(0.005)
        _lControleParametre(csteParam.nomTable_Mortalite_H).setValeurUniqueFromObject("Table_DC_Empr_H.sas7bdat")
        _lControleParametre(csteParam.nomtble_maintien_incinvFRA).setValeurUniqueFromObject("abatFra_INCINV_90_CNP.sas7bdat")
        _lControleParametre(csteParam.nomGrilleTarifaire).setValeurUniqueFromObject("tarifBPLC.sas7bdat")
        _lControleParametre(csteParam.nomTble_maintien_incinvM2).setValeurUniqueFromObject("MaintINCINV_CNP_MENS.sas7bdat")
        Dim defautSelectionMedicale(1) As Double
        defautSelectionMedicale(0) = 0.5
        defautSelectionMedicale(1) = 0.25
        _lControleParametre(csteParam.nomSel_medic).setValeurUniqueFromObject(defautSelectionMedicale)
    End Sub

    Public Sub addRegle(ByVal nomParametre As String, ByVal regle As Object) _
        Implements IListControleursParametres.addRegle
        _lControleParametre(nomParametre).addRegle(regle)
    End Sub
    Public Function isValeurUniqueAfficheeValide(ByVal nomParametre As String, _
                                                 ByVal valeurUniqueAffichee As String) _
                                                 As resultatValidationContraintes Implements IListControleursParametres.isValeurUniqueAfficheeValide
        'Cette fonction permet de tester la validité d'une valeur unique telle qu'affichée par les écrans
        Return _lControleParametre(nomParametre).isValeurUniqueAfficheeValide(valeurUniqueAffichee)
    End Function
    Public Function isValide(ByVal nomParametre As String, ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes _
        Implements IListControleursParametres.isValide
        Return Nothing
    End Function
    Public Function isListeParametresValide() As resultatValidationContraintes Implements IListControleursParametres.isListeParametresValide
        Dim result As New resultatValidationContraintes
        result.isValide = True
        result.msg = ""
        For Each controleurParametre As controleurParamNonTyped In _lControleParametre.Values
            If controleurParametre.getNature = paramNature.Null Then
                result.isValide = False
                result.msg = result.msg & "Le paramètre '" & controleurParametre.getDescription & "' n'est pas valide" & vbCrLf
            End If
        Next
        Return result
    End Function
    Public Function setValeursDataTable(ByVal nomParametre As String, ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes _
        Implements IListControleursParametres.setValeursDataTable
        Return _lControleParametre(nomParametre).setValeursDataTable(valeursDataTable)
    End Function
    Public Function setValeursFromExt(ByVal nomParametre As String, ByVal valeursExt As System.Data.DataTable) As resultatValidationContraintes _
        Implements IListControleursParametres.setValeursFromExt
        Return _lControleParametre(nomParametre).setValeursDataTableFromExt(valeursExt)
    End Function
    Public Function setValeurUniqueFromObject(ByVal nomParametre As String, ByVal valeurUnique As Object) As resultatValidationContraintes _
        Implements IListControleursParametres.setValeurUniqueFromObject
        Return _lControleParametre(nomParametre).setValeurUniqueFromObject(valeurUnique)
    End Function
    Public Function setValeurUniqueFromValeurAffichee(ByVal nomParametre As String, ByVal valeurUnique As String) As resultatValidationContraintes _
        Implements IListControleursParametres.setValeurUniqueFromValeurAffichee
        Return _lControleParametre(nomParametre).setValeurUniqueFromValeurVue(valeurUnique)
    End Function

    Public Function getDescription(ByVal nomParametre As String) As String Implements IListControleursParametres.getDescription
        Return _lControleParametre(nomParametre).getDescription
    End Function
    Public Function getNature(ByVal nomParametre As String) As paramNature Implements IListControleursParametres.getNature
        Return _lControleParametre(nomParametre).getNature
    End Function
    Public Function getMethode_Cal(ByVal nomParametre As String) As Boolean() Implements IListControleursParametres.getMethode_cal
        Return _lControleParametre(nomParametre).getMethode_cal
    End Function
    Public Function getValeurUniqueAffichee(ByVal nomParametre As String) As String Implements IListControleursParametres.getValeurUniqueAffichee
        Return _lControleParametre(nomParametre).getValeurUniqueAffichee()
    End Function
    Public Function getValeurUnique(ByVal nomParametre As String) As Object _
        Implements IListControleursParametres.getValeurUnique
        Return _lControleParametre(nomParametre).getValeurUnique
    End Function
    Public Function getValeursDataTable(ByVal nomParametre As String) As DataTable _
        Implements IListControleursParametres.getValeursDataTable
        Return _lControleParametre(nomParametre).getValeursDataTable
    End Function
    Public Function getValeursSeg(ByVal nomParametre As String) As List(Of String) Implements IListControleursParametres.getValeursSeg
        Return _lControleParametre(nomParametre).getValeursSeg
    End Function
    Public Function getControleur(ByVal nomParametre As String) As controleurParamNonTyped Implements IListControleursParametres.getControleur
        Return _lControleParametre.Item(nomParametre)
    End Function
End Class
#End Region

#Region "Contrôleur individuel non typé"
Public MustInherit Class controleurParamNonTyped
    Public MustOverride Function setValeurUniqueFromValeurVue(ByVal valeurUniqueVue As String) As resultatValidationContraintes
    Public MustOverride Function setValeurUniqueFromObject(ByVal valeurUniqueObjet As Object) As resultatValidationContraintes
    Public MustOverride Function setValeursDataTable(ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes
    Public MustOverride Function setValeursDataTableFromExt(ByVal ext As System.Data.DataTable) As resultatValidationContraintes
    Public MustOverride Function setMethode_Cal(ByVal methodesCalcul As Boolean()) As resultatValidationContraintes

    Public MustOverride Function isValeurUniqueAfficheeValide(ByVal valeurUniqueAffichee As String) As resultatValidationContraintes
    Protected MustOverride Function isValide(ByVal valeursDataTable As DataTable) As resultatValidationContraintes
    Public MustOverride Function addRegle(ByVal regle As Object) As resultatValidationContraintes

    Public MustOverride Function getValeurUniqueAffichee() As String
    Public MustOverride Function getDescription() As String
    Public MustOverride Function getNature() As paramNature
    Public MustOverride Function getMethode_cal() As Boolean()
    Public MustOverride Function getValeurUnique() As Object
    Public MustOverride Function getValeursDataTable() As DataTable
    Public MustOverride Function getValeursSeg() As List(Of String)
End Class
#End Region

#Region "Contrôleur individuel typé"

Public MustInherit Class controleurParamTyped(Of typeParametre)
    Inherits controleurParamNonTyped

#Region "Variables de classe"
    'Objet métier encapsuler pour contrôler/transformer les valeurs entrantes
    Protected _typedParam As generiqueTypedParametreV2(Of typeParametre)
    'Implémentation des comportements susceptible d'évoluer au sein du contrôleur de paramètres
    'Tableau des règles associées au paramètre
    Protected _lRegle As New List(Of IRegle(Of typeParametre))
    Protected _implGestCorrespValeurs As IGestionCorrespValeurs
    Protected _implGestConversions As IGestionConversions
#End Region

#Region "Constructeur"
    'Le gestionnaire de correspondance ne peut être égal à nothing.
    'En revanche, le gestionnaire de conversions peut l'être
    Public Sub New(ByVal typedParam As generiqueTypedParametreV2(Of typeParametre), _
                   ByVal gestionnaireCorrespValeurs As IGestionCorrespValeurs, _
                   Optional ByVal gestionnaireConversions As IGestionConversions = Nothing)
        _implGestCorrespValeurs = IIf(gestionnaireCorrespValeurs Is Nothing, _
                                      New defautGestionCorrespValeurs(), _
                                      gestionnaireCorrespValeurs)
        _implGestConversions = gestionnaireConversions
        _typedParam = typedParam
    End Sub
#End Region

#Region "Redéfinition des méthodes du contrôleur non typé et permettant de modifier le paramètre"
    ''' <summary>
    ''' Contrôle d'une affectation directe de valeur unique au paramètre
    ''' </summary>
    ''' <param name="valeurUniqueObjet"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeurUniqueFromObject(ByVal valeurUniqueObjet As Object) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        Try
            Dim typedValeur As typeParametre = CType(valeurUniqueObjet, typeParametre)
            result = setValeurUnique(typedValeur)
        Catch ex As Exception
            If _implGestConversions Is Nothing Then
                result.isValide = False
                result.msg = "Valeur incompatible avec le type du paramètre (" & _typedParam.type.Name & ")."
            End If
        Finally
        End Try
        Return result
    End Function
    ''' <summary>
    ''' Contrôle d'une affectation de valeur unique au paramètre à partir d'une valeur récupérée dans une vue
    ''' au format chaîne de caractère
    ''' </summary>
    ''' <param name="valeurUniqueVue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeurUniqueFromValeurVue(ByVal valeurUniqueVue As String) As resultatValidationContraintes


        Dim result As New resultatValidationContraintes
        Dim valeurUnique As typeParametre
        'Si la valeur vue est vide, on met la valeur du paramètre à nothing
        If valeurUniqueVue = "" Or valeurUniqueVue = "-" Then
            valeurUnique = Nothing
            result = _typedParam.setValeurToNothing()
        Else
            'Si la valeur vue n'est pas vide, on test l'existance d'une correspondance de valeurs
            Try
                valeurUnique = _implGestCorrespValeurs.valeurStockeeFromValeurAffichee(Of typeParametre)(valeurUniqueVue)
                'Une correspondance a été trouvée
                result = setValeurUnique(valeurUnique)
            Catch ex As Exception
                'Aucune correspondance n'a été trouvée
                result.isValide = False
                result.msg = ("La valeur entrée n'est pas valide pour ce paramètre")
                Return result
            End Try
        End If
        Return result


    End Function
    ''' <summary>
    ''' Contrôle d'une affectation de valeur unique déjà typée au paramètre
    ''' </summary>
    ''' <param name="valeurUnique"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function setValeurUnique(ByVal valeurUnique As typeParametre, _
                                    Optional ByVal verifUniquement As Boolean = False) _
                                    As resultatValidationContraintes
        'Vérifier que la valeur est correcte à l'aide de l'objet gérant les contraintes sur les valeurs
        Dim result As New resultatValidationContraintes
        If valeurUnique Is Nothing Then
            result = _typedParam.setValeurUnique(Nothing)
        Else
            result = isValide(valeurUnique)
            If result.isValide And Not verifUniquement Then
                result = _typedParam.setValeurUnique(valeurUnique)
            End If
        End If
        Return result
    End Function
    ''' <summary>
    ''' Contrôle d'une affectation de valeurs multiples au paramètre
    ''' </summary>
    ''' <param name="valeursDataTable"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeursDataTable(ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result = valideFormatValeursDataTable(valeursDataTable)
        If result.isValide Then
            result = isValide(valeursDataTable)
            If result.isValide Then
                _typedParam.setValeursDataTable(valeursDataTable)
            End If
        End If
        Return result
    End Function
    ''' <summary>
    ''' Affectation d'une valeur à partir d'une extraction de ses segments
    ''' </summary>
    ''' <param name="ext"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeursDataTableFromExt(ByVal ext As System.Data.DataTable) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        'Ici, pas de vérificateur, on se contente d'ajouter une colonne
        ext.Columns.Add(_typedParam.nom, GetType(typeParametre))
        'Récupération de la table des valeurs et identification des colonnes portant le même nom
        _typedParam.setValeursDataTable(ext)
        Return result
    End Function
    ''' <summary>
    ''' Affectation d'un tableau indiquant les méthodes de calcul utilisant le paramètre
    ''' </summary>
    ''' <param name="methodesCalcul"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setMethode_Cal(ByVal methodesCalcul() As Boolean) As resultatValidationContraintes
        _typedParam.methode_Cal = methodesCalcul
        Dim result As New resultatValidationContraintes
        result.isValide = True
        result.msg = ""
        Return result
    End Function
#End Region

#Region "Paramétrage/exécution des fonctions validatrices"

    Public Overrides Function isValeurUniqueAfficheeValide(ByVal valeurUniqueAffichee As String) As PTIC_Util.resultatValidationContraintes

        Dim result As New resultatValidationContraintes
        Dim valeurUnique As typeParametre
        'Si la valeur vue est vide, on valide la valeur comme possible (les paramètres acceptent des valeurs uniques vides)
        If valeurUniqueAffichee = "" Then
            result.isValide = True
            result.msg = "Valeur Vide"
        Else
            'Si la valeur vue n'est pas vide, on test l'existance d'une correspondance de valeurs
            Try
                valeurUnique = _implGestCorrespValeurs.valeurStockeeFromValeurAffichee(Of typeParametre)(valeurUniqueAffichee)
                If valeurUnique Is Nothing Then
                    result.isValide = False
                    result.msg = "Valeur invalide"
                Else
                    result = isValide(valeurUnique)
                End If
            Catch ex As Exception
                'Aucune correspondance n'a été trouvée
                result.isValide = False
                result.msg = ("La valeur entrée n'est pas valide pour ce paramètre")
                Return result
            End Try
        End If
        Return result

    End Function
    Protected Overrides Function isValide(ByVal valeursDataTable As DataTable) As resultatValidationContraintes
        Dim result As resultatValidationContraintes = valideFormatValeursDataTable(valeursDataTable)
        If result.isValide Then
            For Each r As DataRow In valeursDataTable.Rows
                Dim valeurUnique As typeParametre = r(_typedParam.nom)
                If Not isValide(valeurUnique).isValide Then
                    result = isValide(valeurUnique)
                End If
            Next
        End If

        Return result
    End Function
    Protected Overloads Function isValide(ByVal valeurUnique As typeParametre) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True

        If valeurUnique Is Nothing Then
            result.msg = "Valeur de paramètre nulle"
            result.isValide = False
        Else

            For Each regle As IRegle(Of typeParametre) In _lRegle
                If Not regle.executeRegle(valeurUnique).isValide Then
                    result.isValide = False
                    result.msg = regle.executeRegle(valeurUnique).msg
                End If
            Next

        End If

        Return result
    End Function

    Public Overrides Function addRegle(ByVal regle As Object) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        Dim regleTyped As IRegle(Of typeParametre)
        Try
            regleTyped = regle
            _lRegle.Add(regleTyped)
        Catch ex As Exception
            result.isValide = False
            result.msg = "La règle que vous tentez d'ajouter au paramètre est incompatible avec le type de ce paramètre"
        Finally
        End Try
        Return result
    End Function
    Public Overloads Function addRegle(ByVal regle As IRegle(Of typeParametre)) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        _lRegle.Add(regle)
        Return result
    End Function

    Protected Function valideFormatValeursDataTable(ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        If valeursDataTable Is Nothing Then
            result.msg = "La table en paramètre est vide"
            result.isValide = False
        ElseIf Not valeursDataTable.Columns.Contains(_typedParam.nom) Then
            result.msg = "Colonne " & _typedParam.nom & " absente de la table en paramètre"
            result.isValide = False
        ElseIf valeursDataTable.Rows.Count = 0 Then
            'On teste que la table contient au moins une ligne (sinon aucune valeur n'est affectée au paramètre)
            result.msg = "La table doit contenir au moins une ligne de données"
            result.isValide = False
            'ElseIf Not valeursDataTable.Columns("Valeurs").GetType = parametreRattachement.getType Then
        ElseIf Not valeursDataTable.Columns(_typedParam.nom).DataType.FullName = GetType(typeParametre).FullName Then
            'On test que le type de la colonne valeur correspond bien au type du paramètre
            result.msg = "La table des valeurs n'est pas du même type que le paramètre"
            result.isValide = False
        End If
        Return result
    End Function

#End Region

#Region "Consultation des valeurs d'un paramètre (conservée avant passage à un MVC total)"
    Public Overrides Function getMethode_cal() As Boolean()
        Return _typedParam.methode_Cal()
    End Function
    Public Overrides Function getValeurUniqueAffichee() As String
        'Dim result As New resultatValidationContraintes
        Dim result As String = ""
        Dim valeurUnique As typeParametre = _typedParam.getValeurUnique()
        If _typedParam.nature <> paramNature.Unique Then result = ""
        If _typedParam.nature = paramNature.Unique Then
            result = _implGestCorrespValeurs.valeurAfficheeFromValeurStockee(Of typeParametre)(valeurUnique)
        End If
        Return result
    End Function
    Public Overrides Function getDescription() As String
        Return _typedParam.description
    End Function
    Public Overrides Function getNature() As paramNature
        Return _typedParam.nature
    End Function
    Public Overrides Function getValeurUnique() As Object
        Return _typedParam.getValeurUnique
    End Function
    Public Overrides Function getValeursDataTable() As System.Data.DataTable
        Return _typedParam.getValeursDataTable
    End Function
    Public Overrides Function getValeursSeg() As System.Collections.Generic.List(Of String)
        Return _typedParam.getValeursSegments
    End Function
#End Region

End Class

Public Class defautControleurParamTyped(Of typeParametre)
    Inherits controleurParamTyped(Of typeParametre)
    Public Sub New(ByVal paramTyped As generiqueTypedParametreV2(Of typeParametre), _
                   ByVal gestionnaireCorrespValeurAffStock As IGestionCorrespValeurs, _
                   ByVal gestionnaireConversions As IGestionConversions)
        MyBase.New(paramTyped, gestionnaireCorrespValeurAffStock, gestionnaireConversions)
    End Sub
End Class

Public Class controleurSelectionMedicale
    Inherits controleurParamNonTyped
#Region "Variables de classe"
    'Objet métier encapsulé pour contrôle/transformation des valeurs entrantes
    Protected _typedParam As parametreSelectionMedicale
    'Implémentation des comportements susceptible d'évoluer au sein du contrôleur de paramètres
    'Tableau des règles associées au paramètre
    Protected _lRegle As New List(Of IRegle(Of Double)) 'Les valeurs à valider sont les taux d'abattement (et donc des décimaux)
    Protected _implGestCorrespValeurs As IGestionCorrespValeurs 'Dans le cas de la sélection médicale, pas besoin de gérer des correspondances
    Protected _implGestConversions As IGestionConversions 'Ici, les conversions se font entre les chaines de caractère et les double
#End Region
#Region "Constructeur"
    'Le gestionnaire de correspondance ne peut être égal à nothing.
    'En revanche, le gestionnaire de conversions peut l'être
    Public Sub New(ByVal typedParam As parametreSelectionMedicale, _
                   Optional ByVal gestionnaireCorrespValeurs As IGestionCorrespValeurs = Nothing, _
                   Optional ByVal gestionnaireConversions As IGestionConversions = Nothing)
        _implGestCorrespValeurs = IIf(gestionnaireCorrespValeurs Is Nothing, _
                                      New defautGestionCorrespValeurs(), _
                                      gestionnaireCorrespValeurs)
        _implGestConversions = gestionnaireConversions
        _typedParam = typedParam
    End Sub
#End Region
#Region "Redéfinition des méthodes du contrôleur non typé et permettant de modifier le paramètre"
    Public Sub setNbMaxDeroulement(ByVal nbMaxDeroulement As Integer)
        _typedParam.maxDeroulement = nbMaxDeroulement
    End Sub
    ''' <summary>
    ''' Contrôle d'une affectation directe de valeur unique au paramètre
    ''' </summary>
    ''' <param name="valeurUniqueObjet"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeurUniqueFromObject(ByVal valeurUniqueObjet As Object) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        Try
            Dim typedValeur As Double() = CType(valeurUniqueObjet, Double())
            result = setValeurUnique(typedValeur)
        Catch ex As Exception
            If _implGestConversions Is Nothing Then
                result.isValide = False
                result.msg = "Valeur incompatible avec le type du paramètre (" & _typedParam.type.Name & ")."
            End If
        Finally
        End Try
        Return result
    End Function
    Public Function setValeurUnique(ByVal valeurUnique As Double(), _
                                    Optional ByVal verifUniquement As Boolean = False) _
                                    As resultatValidationContraintes

        'Vérifier que la valeur est correcte à l'aide de l'objet gérant les contraintes sur les valeurs
        Dim result As New resultatValidationContraintes
        If valeurUnique Is Nothing Then
            result = _typedParam.setValeurToNothing
        Else
            result = isValide(valeurUnique)
            If result.isValide And Not verifUniquement Then
                _typedParam.setValeurUnique(valeurUnique)
            End If
        End If
        Return result

    End Function
    ''' <summary>
    ''' Affectation d'une valeur à partir d'une extraction de ses segments
    ''' </summary>
    ''' <param name="ext"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeursDataTableFromExt(ByVal ext As System.Data.DataTable) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        _typedParam.setValeursFromExt(ext)
        Return result
    End Function
    ''' <summary>
    ''' Affectation d'un tableau indiquant les méthodes de calcul utilisant le paramètre
    ''' </summary>
    ''' <param name="methodesCalcul"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setMethode_Cal(ByVal methodesCalcul() As Boolean) As resultatValidationContraintes
        _typedParam.methode_Cal = methodesCalcul
        Dim result As New resultatValidationContraintes
        result.isValide = True
        result.msg = ""
        Return result
    End Function
#Region "Sans objet pour la sélection médicale"
    ''' <summary>
    ''' Contrôle d'une affectation de valeur unique au paramètre à partir d'une valeur récupérée dans une vue
    ''' au format chaîne de caractère
    ''' </summary>
    ''' <param name="valeurUniqueVue"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeurUniqueFromValeurVue(ByVal valeurUniqueVue As String) As resultatValidationContraintes
        MsgBox("Sans objet pour la sélection médicale")
        Return Nothing
    End Function
    ''' <summary>
    ''' Contrôle d'une affectation de valeurs multiples au paramètre
    ''' </summary>
    ''' <param name="valeursDataTable"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Overrides Function setValeursDataTable(ByVal valeursDataTable As System.Data.DataTable) _
        As resultatValidationContraintes
        MsgBox("Sans objet pour la sélection médicale")
        Return Nothing
    End Function
#End Region
#End Region
#Region "Paramétrage/exécution des fonctions validatrices"
    Public Overrides Function isValeurUniqueAfficheeValide(ByVal valeurElementaireAffichee As String) As PTIC_Util.resultatValidationContraintes

        Dim result As New resultatValidationContraintes
        Dim valeurElementaire As Double
        'Si la valeur vue est vide, on valide la valeur comme possible (les paramètres acceptent des valeurs uniques vides)
        If valeurElementaireAffichee = "" Then
            result.isValide = True
            result.msg = "Valeur Vide"
        Else
            'Si la valeur vue n'est pas vide, on test l'existance d'une correspondance de valeurs
            Try
                valeurElementaire = _implGestCorrespValeurs.valeurStockeeFromValeurAffichee(Of Double)(valeurElementaireAffichee)
                result = isValide(valeurElementaire)
            Catch ex As Exception
                'Aucune correspondance n'a été trouvée
                result.isValide = False
                result.msg = ("La valeur entrée n'est pas valide pour ce paramètre")
                Return result
            End Try
        End If
        Return result

    End Function
    Protected Overrides Function isValide(ByVal valeursDataTable As DataTable) As resultatValidationContraintes
        MsgBox("Sans objet pour la sélection médicale, une dataTable est validée au cours de la saisie")
        Return Nothing
    End Function
    Protected Overloads Function isValide(ByVal valeurElementaire As Double) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        For Each regle As IRegle(Of Double) In _lRegle
            If Not regle.executeRegle(valeurElementaire).isValide Then
                result.isValide = False
                result.msg = regle.executeRegle(valeurElementaire).msg
            End If
        Next
        Return result
    End Function
    Protected Overloads Function isValide(ByVal valeurUnique As Double()) As resultatValidationContraintes

        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True

        If valeurUnique Is Nothing Then
            result.msg = "Valeur de paramètre nulle"
            result.isValide = False

        Else
            For i As Integer = 0 To valeurUnique.Count - 1
                If Not isValide(valeurUnique(i)).isValide Then
                    result.msg = result.msg & isValide(valeurUnique(i)).msg
                    result.isValide = False
                End If
            Next

        End If

        Return result
    End Function
    Public Overrides Function addRegle(ByVal regle As Object) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        Dim regleTyped As IRegle(Of Double)
        Try
            regleTyped = regle
            _lRegle.Add(regleTyped)
        Catch ex As Exception
            result.isValide = False
            result.msg = "La règle que vous tentez d'ajouter au paramètre est incompatible avec le type de ce paramètre"
        Finally
        End Try
        Return result
    End Function
    Public Overloads Function addRegle(ByVal regle As IRegle(Of Double)) As resultatValidationContraintes
        Dim result As New resultatValidationContraintes
        result.msg = ""
        result.isValide = True
        _lRegle.Add(regle)
        Return result
    End Function
    Protected Function valideFormatValeursDataTable(ByVal valeursDataTable As System.Data.DataTable) As resultatValidationContraintes
        MsgBox("Sans objet pour la sélection médicale")
        Return Nothing
    End Function
#End Region
#Region "Consultation des valeurs d'un paramètre (conservée avant passage à un MVC total)"
    Public Overrides Function getMethode_cal() As Boolean()
        Return _typedParam.methode_Cal()
    End Function
    Public Overrides Function getValeurUniqueAffichee() As String
        MsgBox("Sans objet pour la sélection médicale")
        Return Nothing
    End Function
    Public Overrides Function getDescription() As String
        Return _typedParam.description
    End Function
    Public Overrides Function getNature() As paramNature
        Return _typedParam.nature
    End Function
    Public Overrides Function getValeurUnique() As Object
        Return _typedParam.getValeurUnique
    End Function
    Public Overrides Function getValeursDataTable() As System.Data.DataTable
        Return _typedParam.getValeursDataTable
    End Function
    Public Overrides Function getValeursSeg() As System.Collections.Generic.List(Of String)
        Return _typedParam.getValeursSegments
    End Function
    Public Function getNbMaxDeroulement() As Integer
        Return _typedParam.maxDeroulement
    End Function
#End Region
End Class

#End Region

#Region "Fabrique de contrôleurs typés"
Public Interface fabriqueControleurParametreTyped
    Function newcontroleur(Of typeParametre)(ByVal typedParam As generiqueTypedParametreV2(Of typePArametre)) As controleurParamTyped(Of typePArametre)
End Interface
Public Class fabriqueDefautNoCorrespControleur
    Implements fabriqueControleurParametreTyped
    Public Sub New()

    End Sub
    Public Function newcontroleur(Of typeParametre)(ByVal typedParam As generiqueTypedParametreV2(Of typeParametre)) As controleurParamTyped(Of typeParametre) Implements fabriqueControleurParametreTyped.newcontroleur
        Return New defautControleurParamTyped(Of typeParametre)(typedParam, Nothing, Nothing)
    End Function
End Class
Public Class fabriqueDefautCorrespDataTableControleur
    Implements fabriqueControleurParametreTyped
    Protected _dtbleCorresp As DataTable
    Public Sub New(ByVal dtbleCorresp As DataTable)
        _dtbleCorresp = dtbleCorresp
    End Sub
    Public Function newcontroleur(Of typeParametre)(ByVal typedParam As generiqueTypedParametreV2(Of typeParametre)) As controleurParamTyped(Of typeParametre) Implements fabriqueControleurParametreTyped.newcontroleur
        Return New defautControleurParamTyped(Of typeParametre)(typedParam, New dataTableGestionCorrespValeurs(_dtbleCorresp), Nothing)
    End Function
End Class
#End Region

#Region "Implémentation des règles"
Public Interface IRegle(Of typeParametre)
    Function executeRegle(ByVal valeur As typeParametre) As resultatValidationContraintes
End Interface
Public Class RegleGenerique(Of typeParametre)
    Implements IRegle(Of typeParametre)

    'Création du type 'Procédure sans argument'
    Public Delegate Function fonctionRegle(ByVal valeur As typeParametre) As Boolean

    'Création d'une variable de type procedureSansArg
    Protected _regleAexecuter As fonctionRegle
    Protected _msgSiErreur As String

    Public Sub New(ByVal regle As fonctionRegle, ByVal msgSiErreur As String)
        _regleAexecuter = regle
        _msgSiErreur = msgSiErreur
    End Sub
    Public Function executeRegle(ByVal valeur As typeParametre) As resultatValidationContraintes _
        Implements IRegle(Of typeParametre).executeRegle
        Dim result As resultatValidationContraintes
        result.isValide = _regleAexecuter.Invoke(valeur)
        If result.isValide Then
            result.msg = ""
        Else
            result.msg = _msgSiErreur
        End If
        Return result
    End Function
End Class
#End Region

#Region "Implémentation des conversions"

#End Region

#Region "Implémentation des correspondances valeurs affichées / valeurs stockées"
Public Interface IGestionCorrespValeurs
    Function valeurAfficheeFromValeurStockee(Of typeParam)(ByVal valeurStockee As typeParam) As String
    Function valeurStockeeFromValeurAffichee(Of typeParam)(ByVal valeurAffichee As String) As typeParam
End Interface
Public Class defautGestionCorrespValeurs
    Implements IGestionCorrespValeurs
    Public Function valeurAfficheeFromValeurStockee(Of typeParam)(ByVal valeurStockee As typeParam) As String Implements IGestionCorrespValeurs.valeurAfficheeFromValeurStockee
        Return valeurStockee.ToString
    End Function
    Public Function valeurStockeeFromValeurAffichee(Of typeParam)(ByVal valeurAffichee As String) As typeParam Implements IGestionCorrespValeurs.valeurStockeeFromValeurAffichee
        Dim obj As Object = valeurAffichee
        Return CType(obj, typeParam)
    End Function
End Class
Public Class dataTableGestionCorrespValeurs
    Implements IGestionCorrespValeurs

    Protected _correspValeurs As DataTable

    Public Sub New(ByVal correspValeurs As DataTable)
        _correspValeurs = correspValeurs
        'Vérifier ici le format de la table transmise en entrée (une colonne valAff et une colonne Aff au bon format)
    End Sub

    'Récupère en entrée une dataTable représentant les valeurs possibles du paramètre et la valeur
    'affichée correspondante
    'Si la valeur n'est pas trouvée dans la dataTable, la fonction renvoie nothing
    Public Function valeurAfficheeFromValeurStockee(Of typeParam)(ByVal valeurStockee As typeParam) As String Implements IGestionCorrespValeurs.valeurAfficheeFromValeurStockee
        Dim result As String = ""
        'Filtre sur la table de correspondance pour retrouver le boolean corresondant au texte
        'récupéré en paramètre
        Dim query = _
            From _valeursCorresp In _correspValeurs.AsEnumerable _
            Where _valeursCorresp.Field(Of typeParam)("val").Equals(valeurStockee) _
            Select _valeursCorresp
        Dim dtTableVal As DataTable = query.CopyToDataTable

        result = (dtTableVal.Rows(0)("valAff"))
        Return result
    End Function

    'Si la valeur affichée n'est pas trouvée dans les valeurs possibles à afficher, la fonction renvoie nothing
    Public Function valeurStockeeFromValeurAffichee(Of typeParam)(ByVal valeurAffichee As String) As typeParam _
        Implements IGestionCorrespValeurs.valeurStockeeFromValeurAffichee

        'Filtre sur la table de correspondance pour retrouver le boolean corresondant au texte
        'récupéré en paramètre
        Dim query = _
            From _valeursCorresp In _correspValeurs.AsEnumerable _
            Where _valeursCorresp.Field(Of String)("valAff") = valeurAffichee _
            Select _valeursCorresp
        Dim dtTableVal As DataTable = query.CopyToDataTable
        Return dtTableVal.Rows(0)("val")

    End Function

End Class
#End Region
